home *** CD-ROM | disk | FTP | other *** search
- ;
- ;
- ; Concurrent copy bug fixed version
- ; 31 May, 1992 TM
- ; 17 Jun, 1992 TM
- ; 15 Sep, 1992 TM GENERIC version
- ; 05 Oct, 1992 HL SCSI_Direct implemented
- ; 22 Oct, 1992 HL SCSI_Direct SendIO() bug fixed
- ; 25 Oct, 1992 HL SCSI_Direct does now return scsi_Status
- ;
- SECTION section
-
- NOLIST
- include "exec/types.i"
- include "exec/nodes.i"
- include "exec/lists.i"
- include "exec/libraries.i"
- include "exec/devices.i"
- include "exec/io.i"
- include "exec/alerts.i"
- include "exec/initializers.i"
- include "exec/memory.i"
- include "exec/resident.i"
- include "exec/ables.i"
- include "exec/errors.i"
- include "exec/tasks.i"
- include "devices/scsidisk.i"
- include 'libraries/expansion.i'
- include 'libraries/configvars.i'
- include 'libraries/configregs.i'
-
- include "asmsupp.i"
- include "mydev.i"
- include "scsi.i"
-
- LIST
-
- XREF SCSIRdWt
- XREF SCSIDirectCmd
-
- ;------ These don't have to be external, but it helps some
- ;------ debuggers to have them globally visible
- XDEF Init
- XDEF Open
- XDEF Close
- XDEF Expunge
- XDEF Null
- XDEF myName
- XDEF BeginIO
- XDEF AbortIO
-
- XLIB AddIntServer
- XLIB RemIntServer
- XLIB Debug
- XLIB InitStruct
- XLIB InitCode
- XLIB OpenLibrary
- XLIB CloseLibrary
- XLIB Alert
- XLIB FreeMem
- XLIB Remove
- XLIB AllocMem
- XLIB AddTask
- XLIB RemTask
- XLIB ReplyMsg
- XLIB Signal
- XLIB GetMsg
- XLIB PutMsg
- XLIB Wait
- XLIB WaitPort
- XLIB AllocSignal
- XLIB SetTaskPri
- XLIB GetCurrentBinding ; Get list of boards for this driver
- XLIB MakeDosNode
- XLIB AddDosNode
- XLIB Permit
- XLIB Forbid
-
- INT_ABLES
-
- FirstAddress:
- CLEAR d0
- rts
-
-
- MYPRI EQU 10
-
- initDDescrip:
- ;STRUCTURE RT,0
- DC.W RTC_MATCHWORD ; UWORD RT_MATCHWORD
- DC.L initDDescrip ; APTR RT_MATCHTAG
- DC.L EndCode ; APTR RT_ENDSKIP
- DC.B RTF_AUTOINIT ; UBYTE RT_FLAGS
- DC.B VERSION ; UBYTE RT_VERSION
- DC.B NT_DEVICE ; UBYTE RT_TYPE
- DC.B MYPRI ; BYTE RT_PRI
- DC.L myName ; APTR RT_NAME
- DC.L idString ; APTR RT_IDSTRING
- DC.L Init ; APTR RT_INIT
- ; LABEL RT_SIZE
-
-
- subSysName:
- myName: MYDEVNAME
-
- dosName: DOSNAME
-
- ; a major version number.
- VERSION: EQU 34
-
- REVISION: EQU 3
-
- idString: dc.b 'Spartan 34.3-TM1.1G/HL1.1 (25 OCT 92)',13,10,0
-
- ; force word allignment
- ds.w 0
-
- Init:
- DC.L MyDev_Sizeof ; data space size
- DC.L funcTable ; pointer to function initializers
- DC.L dataTable ; pointer to data initializers
- DC.L initRoutine ; routine to run
-
-
- funcTable:
-
- ;------ standard system routines
- dc.l Open
- dc.l Close
- dc.l Expunge
- dc.l Null
-
- ;------ my device definitions
- dc.l BeginIO
- dc.l AbortIO
-
- ;------ function table end marker
- dc.l -1
-
-
- dataTable:
- INITBYTE LH_TYPE,NT_DEVICE
- INITLONG LN_NAME,myName
- INITBYTE LIB_FLAGS,LIBF_SUMUSED!LIBF_CHANGED
- INITWORD LIB_VERSION,VERSION
- INITWORD LIB_REVISION,REVISION
- INITLONG LIB_IDSTRING,idString
- DC.L 0
-
-
- initRoutine:
- movem.l d0-d1/a0-a1/a3-a5,-(sp) ; Preserve ALL modified registers
- move.l d0,a5
-
- ;------ save a pointer to exec
- move.l a6,md_SysLib(a5)
-
- ;------ save a pointer to our loaded code
- move.l a0,md_SegList(a5)
-
- lea.l dosName,A1 ; Get expansion lib. name
- moveq #0,D0
- CALLSYS OpenLibrary ; Open the expansion library
- move.l d0,md_DosLib(a5)
- bne.s init_end
- ALERT AG_OpenLib!AO_DOSLib
- ; bra init_error
-
- initDosOK:
- ; lea.l ExLibName,a1
- ; moveq #0,d0
- ; CALLSYS OpenLibrary
- ; move.l d0,a3
- ; bne init_OpSuccess
- ; ALERT AG_OpenLib!AO_ExpansionLib
- ; bra init_error
-
- init_OpSuccess:
- ; move.b #$80,NCR+2 ;Resets SCSI bus
- ; move.l #0,a0
- ; move.l #$3ec,d0
- ; move.b #$0,NCR+2 ;Clear Chip for I/O
- ; moveq #$e,d1
- ; move.l a6,-(a7)
- ; move.l a3,a6
- ; CALLSYS InitCode
- ; move.l (a7)+,a6
- ; move.l d0,a4
- ; move.l $20(a4),d0
- ; tst.l d0
- ; beq init_error
- ; move.l d0,md_Base(a5)
- ; bra init_end
- init_error:
- moveq #0,d0
- init_end:
- movem.l (sp)+,d0-d1/a0-a1/a3-a5
- rts
-
-
- Open: ; ( device:a6, iob:a1, unitnum:d0, flags:d1 )
- movem.l d2/a2-a4,-(sp)
- move.l a1,a2 ; save the iob
-
- ;------ see if the unit number is in range
- ;move.l #1,d0
- ;subq.w #1,d0
- cmp.l #MD_NUMUNITS,d0
- bcc.s Open_Error ; unit number out of range
-
- ;------ see if the unit is already initialized
- move.l d0,d2 ; save unit number
- lsl.l #2,d0
- lea.l md_Units(a6,d0.l),a4
- move.l (a4),d0
- bne.s Open_UnitOK
-
- ;------ try and conjure up a unit
- bsr InitUnit
-
- ;------ see if it initialized OK
- move.l (a4),d0
- beq.s Open_Error
-
- Open_UnitOK:
- move.l d0,a3 ; unit pointer in a3
-
- move.l d0,IO_UNIT(a2)
-
- ;------ mark us as having another opener
- addq.w #1,LIB_OPENCNT(a6)
- addq.w #1,UNIT_OPENCNT(a3)
- ;------ prevent delayed expunges
- bclr #LIBB_DELEXP,md_Flags(a6)
- moveq.l #0,d0
-
- Open_End:
- movem.l (sp)+,d2/a2-a4
- rts
-
- Open_Error:
- movem.l d0,-(sp)
- looop2: move.l #1,d0
- cmp.b #0,d0
- bne looop2
- movem.l (sp)+,d0
-
- move.b #IOERR_OPENFAIL,IO_ERROR(a2)
- bra.s Open_End
-
-
- Close: ; ( device:a6, iob:a1 )
- ; movem.l d1/a2-a3,-(sp)
- ;
- ; move.l a1,a2
- ;
- ; move.l IO_UNIT(a2),a3
- ;
- ;------ make sure the iob is not used again
- ; moveq.l #-1,d0
- ; move.l d0,IO_UNIT(a2)
- ; move.l d0,IO_DEVICE(a2)
- ;
- ;------ see if the unit is still in use
- ; subq.w #1,UNIT_OPENCNT(a3)
-
- ; bne.s Close_Device
- ; bsr ExpungeUnit
-
- Close_Device:
- ;------ mark us as having one fewer openers
- ; moveq.l #0,d0
- ; subq.w #1,LIB_OPENCNT(a6)
-
- ;------ see if there is anyone left with us open
- ; bne.s Close_End
-
- ;------ see if we have a delayed expunge pending
- ; btst #LIBB_DELEXP,md_Flags(a6)
- ; beq.s Close_End
-
- ;------ do the expunge
- ; bsr Expunge
-
- Close_End:
- ; movem.l (sp)+,d1/a2-a3
- ; rts
-
-
- Expunge: ; ( device: a6 )
-
- ; movem.l d1/d2/a5/a6,-(sp) ; Best to save ALL modified registers
- ; move.l a6,a5
- ; move.l md_SysLib(a5),a6
-
- ;------ see if anyone has us open
- ; tst.w LIB_OPENCNT(a5)
- ; beq 1$
-
- ;------ it is still open. set the delayed expunge flag
- ; bset #LIBB_DELEXP,md_Flags(a5)
- ; CLEAR d0
- ; bra.s Expunge_End
-
- 1$:
- ;------ go ahead and get rid of us. Store our seglist in d2
- ; move.l md_SegList(a5),d2
-
- ;------ unlink from device list
- ; move.l a5,a1
- ; CALLSYS Remove
- ; move.l md_DosLib(a5),a1
- ; CALLSYS CloseLibrary
-
- ;
- ; device specific closings here...
- ;
-
- ;------ free our memory
- ; CLEAR d0
- ; CLEAR d1
- ; move.l a5,a1
- ; move.w LIB_NEGSIZE(a5),d1
-
- ; sub.w d1,a1
- ; add.w LIB_POSSIZE(a5),d0
- ; add.l d1,d0
-
- ; CALLSYS FreeMem
-
- ;------ set up our return value
- ; move.l d2,d0
-
- Expunge_End:
- ; movem.l (sp)+,d1/d2/a5/a6
- ; rts
-
-
- Null:
- CLEAR d0
- rts
-
-
- InitUnit: ; ( d2:unit number, a3:scratch, a6:devptr )
-
- movem.l d2-d4/a2,-(sp)
-
- ;------ allocate unit memory
- move.l #MyDevUnit_Sizeof,d0
- move.l #MEMF_PUBLIC!MEMF_CLEAR,d1
- LINKSYS AllocMem,md_SysLib(a6)
-
- tst.l d0
- beq InitUnit_End
-
- move.l d0,a3
- move.b d2,mdu_UnitNum(a3) ; initialize unit number
- move.l a6,mdu_Device(a3) ; initialize device pointer
-
-
- ;------ Initialize the stack information
- lea mdu_stack(a3),a0 ; Low end of stack
- move.l a0,mdu_tcb+TC_SPLOWER(a3)
- lea MYPROCSTACKSIZE(a0),a0 ; High end of stack
- move.l a0,mdu_tcb+TC_SPUPPER(a3)
- move.l a3,-(A0) ; argument -- unit ptr
- move.l a0,mdu_tcb+TC_SPREG(a3)
- ;------ initialize the unit's list
- lea MP_MSGLIST(a3),a0
- NEWLIST a0
- lea mdu_tcb(a3),a0
- move.l a0,MP_SIGTASK(a3)
- moveq.l #0,d0 ; Don't need to re-zero it
- move.l a3,a2 ; InitStruct is initializing the UNIT
- lea.l mdu_Init,A1
- LINKSYS InitStruct,md_SysLib(a6)
-
- move.l a3,mdu_is+IS_DATA(a3) ; Pass int. server unit addr.
-
- ; Startup the task
- lea mdu_tcb(a3),a1
- lea Proc_Begin(PC),a2
- move.l a3,-(sp) ; Preserve UNIT pointer
- lea -1,a3 ; generate address error
- ; if task ever "returns"
- CLEAR d0
- LINKSYS AddTask,md_SysLib(a6)
- move.l (sp)+,a3 ; restore UNIT pointer
-
- ;------ mark us as ready to go
- move.l d2,d0 ; unit number
- lsl.l #2,d0
- move.l a3,md_Units(a6,d0.l) ; set unit table
-
-
- InitUnit_End:
- movem.l (sp)+,d2-d4/a2
- rts
- ;------ got an error. free the unit structure that we allocated.
- InitUnit_FreeUnit:
- bsr FreeUnit
- bra.s InitUnit_End
-
- FreeUnit: ; ( a3:unitptr, a6:deviceptr )
- move.l a3,a1
- move.l #MyDevUnit_Sizeof,d0
- LINKSYS FreeMem,md_SysLib(a6)
- rts
-
-
- ExpungeUnit: ; ( a3:unitptr, a6:deviceptr )
- ; move.l d2,-(sp)
-
-
- ; lea mdu_tcb(a3),a1
- ; LINKSYS RemTask,md_SysLib(a6)
-
- ;------ save the unit number
- ; CLEAR d2
- ; move.b mdu_UnitNum(a3),d2
-
- ;------ free the unit structure.
- ; bsr FreeUnit
-
- ;------ clear out the unit vector in the device
- ; lsl.l #2,d2
- ; clr.l md_Units(a6,d2.l)
-
- ; move.l (sp)+,d2
-
- rts
-
- cmdtable:
- DC.L Invalid ; $00000001
- DC.L MyReset ; $00000002
- DC.L RdWt ; $00000004 Common routine for read/write
- DC.L RdWt ; $00000008
- DC.L Update ; $00000010
- DC.L Clear ; $00000020
- DC.L MyStop ; $00000040
- DC.L Start ; $00000080
- DC.L Flush ; $00000100
- DC.L Motor ; $00000200 motor (NO-OP)
- DC.L Seek ; $00000400 seek (NO-OP)
- DC.L Format ; $00000800 format -> WRITE for harddisk
- DC.L MyRemove ; $00001000 remove (NO-OP)
- DC.L ChangeNum ; $00002000 changenum (Returns 0)
- DC.L ChangeState ; $00004000 changestate (Returns 0)
- DC.L ProtStatus ; $00008000 protstatus (Returns 0)
- DC.L RawRead ; Not supported (INVALID)
- DC.L RawWrite ; Not supported (INVALID)
- DC.L GetDriveType ; Get drive type (Returns 1)
- DC.L GetNumTracks ; Get number of tracks (Returns NUMTRKS)
- DC.L AddChangeInt ; Add disk change interrupt (NO-OP)
- DC.L RemChangeInt ; Remove disk change interrupt ( NO-OP)
- DC.L Invalid
- DC.L Invalid
- DC.L Invalid
- DC.L Invalid
- DC.L Invalid
- DC.L Invalid
- DC.L SCSIDirect
- cmdtable_end:
-
- ; this define is used to tell which commands should not be queued
- ; command zero is bit zero.
- ; The immediate commands are Invalid, Reset, Stop, Start, Flush
- IMMEDIATES EQU $000001c3
-
- ; These commands can NEVER be done "immediately" if using interrupts,
- ; since they would "wait" for the interrupt forever!
- ; Read, Write, Format
- NEVERIMMED EQU $0000080C
- ;
- ; BeginIO starts all incoming io. The IO is either queued up for the
- ; unit task or processed immediately.
- ;
-
- BeginIO: ; ( iob: a1, device:a6 )
- movem.l d0/d1/a0/a3,-(sp)
-
- ;------ bookkeeping
- move.l IO_UNIT(a1),a3
-
- ;------ see if the io command is within range
- move.w IO_COMMAND(a1),d0
- cmp.w #MYDEV_END,d0
- bcc BeginIO_NoCmd
- cmp.w #4,d0
- beq BeginIO_NoCmd ;filter UPDATE
- cmp.w #9,d0
- beq BeginIO_NoCmd ;filter MOTOR
- DISABLE a0
-
- ;------ process all immediate commands no matter what
- move.w #IMMEDIATES,d1
- btst d0,d1
- bne.s BeginIO_Immediate
- ;
- ; !!! These lines are enabled so that all read/write requests would be
- ; queued. TM (A cure for the concurrent copy bug)
- ;
- ; IFD INTRRUPT ; if using interrupts, ;DEBUG
- ;------ queue all NEVERIMMED commands no matter what
- move.w #NEVERIMMED,d1
- btst d0,d1
- bne.s BeginIO_QueueMsg
- ; ENDC
-
- ;------ see if the unit is STOPPED. If so, queue the msg.
- btst #MDUB_STOPPED,UNIT_FLAGS(a3)
- bne.s BeginIO_QueueMsg
-
- ;------ this is not an immediate command. see if the device is
- ;------ busy.
- bset #UNITB_ACTIVE,UNIT_FLAGS(a3)
- beq.s BeginIO_Immediate
-
- ;------ we need to queue the device. mark us as needing
- ;------ task attention. Clear the quick flag
- BeginIO_QueueMsg:
- BSET #UNITB_INTASK,UNIT_FLAGS(a3)
- bclr #IOB_QUICK,IO_FLAGS(a1)
-
- ENABLE a0
- move.l a3,a0
- LINKSYS PutMsg,md_SysLib(a6)
- bra BeginIO_End
-
- BeginIO_Immediate:
- ENABLE a0
-
- bsr PerformIO
-
- BeginIO_End:
- movem.l (sp)+,d0/d1/a0/a3
- rts
-
- BeginIO_NoCmd:
- move.b #IOERR_NOCMD,IO_ERROR(a1)
- bra.s BeginIO_End
-
-
- ;
- ; PerformIO actually dispatches an io request. It expects a3 to already
- ; have the unit pointer in it. a6 has the device pointer (as always).
- ; a1 has the io request. Bounds checking has already been done on
- ; the io request.
- ;
-
- PerformIO: ; ( iob:a1, unitptr:a3, devptr:a6 )
- move.l a2,-(sp)
- move.l a1,a2
-
- clr.b IO_ERROR(a2) ; No error so far
- move.w IO_COMMAND(a2),d0
- lsl #2,d0 ; Multiply by 4 to get table offset
- lea cmdtable(pc),a0
- move.l 0(a0,d0.w),a0
-
- jsr (a0)
-
- move.l (sp)+,a2
- rts
-
- ;
- ; TermIO sends the IO request back to the user. It knows not to mark
- ; the device as inactive if this was an immediate request or if the
- ; request was started from the server task.
- ;
-
- TermIO: ; ( iob:a1, unitptr:a3, devptr:a6 )
- move.w IO_COMMAND(a1),d0
- move.w #IMMEDIATES,d1
- btst d0,d1
- bne.s TermIO_Immediate
-
- ;------ we may need to turn the active bit off.
- btst #UNITB_INTASK,UNIT_FLAGS(a3)
- bne.s TermIO_Immediate
-
- ;------ the task does not have more work to do
- bclr #UNITB_ACTIVE,UNIT_FLAGS(a3)
- TermIO_Immediate:
- ;------ if the quick bit is still set then we don't need to reply
- ;------ msg -- just return to the user.
- btst #IOB_QUICK,IO_FLAGS(a1)
- bne.s TermIO_End
-
- LINKSYS ReplyMsg,md_SysLib(a6)
-
- TermIO_End:
- rts
-
- SCSIDirect:
- ; move.b #HFERR_BadStatus,IO_ERROR(a1) ; HL Only if not supported
- ; bsr TermIO
- ; rts
- movem.l a2-a3/a4/a6/d2/d7,-(sp)
- movem.l a6,-(sp)
- move.l IO_DATA(a1),a6
- clr.l IO_ACTUAL(a1)
- clr.l scsi_Actual(a6) ; Initially, no data moved
- move.l scsi_Data(a6),a0
- move.l scsi_Length(a6),d0
- move.l scsi_Command(a6),a2
-
- move.l IO_UNIT(a1),a3 ; Get unit pointer
-
- move.l d0,scsi_Actual(a6)
- CLEAR d2
- move.b mdu_UnitNum(a3),d2
-
- jsr SCSIDirectCmd
-
- move.b d0,IO_ERROR(a1)
- move.b d7,scsi_Status(a6)
- movem.l (sp)+,a6
- bsr TermIO
- movem.l (sp)+,a2-a3/a4/a6/d2/d7
- rts
-
- AbortIO:
- RawRead: ; 10 Not supported (INVALID)
- RawWrite: ; 11 Not supported (INVALID)
- Invalid:
- GetNumTracks:
- move.b #IOERR_NOCMD,IO_ERROR(a1)
- bsr TermIO
- rts
-
- MyReset:
- AddChangeInt:
- RemChangeInt:
- MyRemove:
- Seek:
- Motor:
- Remove:
- ChangeNum:
- ChangeState:
- ProtStatus:
- clr.l IO_ACTUAL(a1) ; Indicate drive isn't protected
- bsr TermIO
- rts
-
- GetDriveType:
- move.l #1,IO_ACTUAL(a1) ; Make it look like 3.5"
- bsr TermIO
- rts
-
- RdWt:
- Format:
- movem.l a2-a3/a6/d2,-(sp)
- clr.l IO_ACTUAL(a1) ; Initially, no data moved
- move.l IO_DATA(a1),a0
- move.l IO_LENGTH(a1),d0
-
- ;------ deal with zero length I/O
- beq.s RdWt_end
-
-
- move.l IO_UNIT(a1),a3 ; Get unit pointer
- move.l a1,a2
-
- * check operation for legality
-
- move.l IO_OFFSET(a2),d1
- move.l d1,d2
- and.l #$1ff,d2
- bne Sec_Error
-
-
- move.l d0,IO_ACTUAL(a2)
- CLEAR d2
- move.b mdu_UnitNum(a3),d2
-
- jsr SCSIRdWt
-
- RdWt_Clean:
- move.b d0,IO_ERROR(a1)
- bra RdWt_end
- Sec_Error:
- move.b #$fc,IO_ERROR(a1)
- RdWt_end:
- bsr TermIO
- movem.l (sp)+,a2-a3/a6/d2
- rts
-
- Update:
- Clear:
- bra Invalid
-
- MyStop:
- bset #MDUB_STOPPED,UNIT_FLAGS(a3)
- bsr TermIO
- rts
-
- Start:
- bsr InternalStart
-
- ; move.l a2,a1 ; TM simul bug
- bsr TermIO
-
- rts
-
- InternalStart:
- ;------ turn processing back on
- move.l a1,-(sp) ; TM simul bug -- save a1
- bclr #MDUB_STOPPED,UNIT_FLAGS(a3)
-
- ;------ kick the task to start it moving
- ; move.l a3,a1 ; TM simul bug
- CLEAR d0
- ; move.l MP_SIGBIT(a3),d1
- move.b MP_SIGBIT(a3),d1 ;TM
- bset d1,d0
- LINKSYS Signal,md_SysLib(a3)
- move.l (sp)+,a1 ; TM simul bug -- restore a1
- rts
-
-
- Flush:
- movem.l d2/a1/a6,-(sp) ; TM simul bug -- save a1
-
- move.l md_SysLib(a6),a6
-
- bset #MDUB_STOPPED,UNIT_FLAGS(a3)
- sne d2
-
- Flush_Loop:
- move.l a3,a0
- CALLSYS GetMsg
-
- tst.l d0
- beq.s Flush_End
-
- move.l d0,a1
- move.b #IOERR_ABORTED,IO_ERROR(a1)
- CALLSYS ReplyMsg
-
- bra.s Flush_Loop
-
- Flush_End:
-
- move.l d2,d0
- movem.l (sp)+,d2/a1/a6 ; TM simul bug
-
- tst.b d0
- beq.s 1$
-
- bsr InternalStart
- 1$:
-
- ; move.l a2,a1 ; TM simul bug
- bsr TermIO
-
- rts
-
- ; cnop 0,4 ; long word allign
- DC.L 16 ; segment length -- any number will do
- myproc_seglist:
- DC.L 0 ; pointer to next segment
-
- ; the next instruction after the segment list is the first executable address
-
- Proc_Begin:
-
- move.l 4,a6
-
- ;------ Grab the argument
- move.l 4(sp),a3 ; Unit pointer
-
- move.l mdu_Device(a3),a5 ; Point to device structure
-
-
-
- ;------ Allocate the right signal
-
- moveq #-1,d0 ; -1 is any signal at all
- CALLSYS AllocSignal
-
- move.b d0,MP_SIGBIT(a3)
- move.b #PA_SIGNAL,MP_FLAGS(a3)
-
- ;------ change the bit number into a mask, and save in d7
-
- moveq #0,d7
- bset d0,d7
-
- bra.s Proc_CheckStatus
-
- ;------ main loop: wait for a new message
- Proc_MainLoop:
- move.l d7,d0
- CALLSYS Wait
-
- Proc_CheckStatus:
- ;------ see if we are stopped
- btst #MDUB_STOPPED,UNIT_FLAGS(a3)
- bne.s Proc_MainLoop ; device is stopped
-
- ;------ lock the device
- bset #UNITB_ACTIVE,UNIT_FLAGS(a3)
- bne.s Proc_MainLoop ; device in use
- ;------ get the next request
- Proc_NextMessage:
- move.l a3,a0
- CALLSYS GetMsg
- tst.l d0
- beq.s Proc_Unlock ; no message?
-
- ;------ do this request
- move.l d0,a1
- exg a5,a6 ; put device ptr in right place
- bsr PerformIO
- exg a5,a6 ; get syslib back in a6
-
- bra.s Proc_NextMessage
-
- ;------ no more messages. back ourselves out.
- Proc_Unlock:
- and.b #$ff&(~(UNITF_ACTIVE!UNITF_INTASK)),UNIT_FLAGS(a3)
- bra Proc_MainLoop
- mdu_Init:
- ; ------ Initialize the device
-
- INITBYTE MP_FLAGS,PA_IGNORE
- INITBYTE LN_TYPE,NT_DEVICE
- INITLONG LN_NAME,myName
- INITBYTE mdu_Msg+LN_TYPE,NT_MSGPORT ;Unit starts with MsgPort
- INITLONG mdu_Msg+LN_NAME,myName
- INITLONG mdu_tcb+LN_NAME,myName
- INITBYTE mdu_tcb+LN_TYPE,NT_TASK
- INITBYTE mdu_tcb+LN_PRI,MYPROCPRI
- INITBYTE mdu_is+LN_PRI,4 ; Int priority 4
- IFD INTRRUPT
- INITLONG mdu_is+IS_CODE,myintr ; Interrupt routine addr
- ENDC
- INITLONG mdu_is+LN_NAME,myName
- DC.L 0
-
- EndCode:
- END ;TM
-